package com.mall.controller;


import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.mall.common.config.JsonUtils;
import com.mall.common.utils.BeanUtils;
import com.mall.domain.dto.*;
import com.mall.domain.po.Item;

import com.mall.domain.response.Response;
import com.mall.domain.vo.UserRoleVO;
import com.mall.service.ItemService;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;


@Slf4j
@RestController
@RequestMapping("/items")
@RequiredArgsConstructor
public class ItemController {

    private final ItemService itemService;
    private final RedisTemplate<String,Object> redisTemplate;
    private final String ITEM_DETAIL ="item:detail:";
    @Resource(name = "taskExecutor")
    private final  ThreadPoolTaskExecutor threadPoolTaskExecutor;
    /**
     * 用户信息本地缓存
     */
    private static final Cache<String , ItemDTO> LOCAL_CACHE = Caffeine.newBuilder()
            .initialCapacity(10000) // 设置初始容量为 10000 个条目
            .maximumSize(10000) // 设置缓存的最大容量为 10000 个条目
            .expireAfterWrite(1, TimeUnit.HOURS) // 设置缓存条目在写入后 1 小时过期
            .build();
    /**
     * 根据id查询商品
     * @param id 商品id
     * @return 商品实体
     */
    @GetMapping("/{id}")
    public ItemDTO selectById(@PathVariable Long id){
        String key=ITEM_DETAIL+id;
        // 先从本地缓存中查询
        ItemDTO ifPresent = LOCAL_CACHE.getIfPresent(key);
        if (!Objects.isNull(ifPresent)){
            // 本地缓存未命中，查询Redis缓存
            String  itemDe = (String)redisTemplate.opsForValue().get(key);
            ItemDTO itemDetail = JsonUtils.parseObject(itemDe, ItemDTO.class);
            if (!Objects.isNull(itemDetail)){
                // Redis缓存命中，异步更新本地缓存
                threadPoolTaskExecutor.execute(()->{
                    LOCAL_CACHE.put(key,itemDetail);
                });

                return itemDetail;
            }
            // 返回本地缓存数据
            return ifPresent;
        }

        // 缓存都未命中，查询数据库
        Item byId = itemService.getById(id);
        if(byId==null)
            return null;
        ItemDTO itemDTO = new ItemDTO();
        BeanUtils.copyProperties(byId,itemDTO);
        // 将查询结果存入Redis缓存，过期时间5-10分钟
        redisTemplate.opsForValue().set(key, JsonUtils.toJsonString(itemDTO),5+ RandomUtil.randomInt(5), TimeUnit.MINUTES);
        return itemDTO;
    }


    /**
     * 根据id批量查询商品
     * @param ids 商品id集合
     * @return 商品实体集合
     */
    @GetMapping
    public List<ItemDTO> selectByIds(@RequestBody List<Long> ids){
        List<ItemDTO> byIds = itemService.getItemByIds(ids);
        if (!byIds.isEmpty()){
            return byIds;
        }
        return null;
    }

    /**
     * 分页查询商品
     * @return 查询的结果
     */
    @GetMapping("/page")
    public PageResponse<Item> selectByPage( @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
                                            @RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize,
                                            @RequestParam(value = "isAsc", defaultValue = "true") Boolean isAsc,
                                            @RequestParam(value = "sortBy", required = false) String sortBy){
        Page<Item> pages = itemService.pages(pageNo,pageSize,isAsc,sortBy);
        PageResponse<Item> itemPageResponse = new PageResponse<>();
        itemPageResponse.setTotal(pages.getTotal());
        itemPageResponse.setPages(pages.getSize());
        itemPageResponse.setList(pages.getRecords());
        return itemPageResponse;
    }

    /**
     * 新增商品
     */
    @PostMapping(value = "/add", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Response<?> insert(
            @RequestParam("name") String name,
            @RequestParam("price") Integer price,
            @RequestParam("stock") Integer stock,
            @RequestParam("image") MultipartFile image,  // 用于接收文件
            @RequestParam("category") String category,
            @RequestParam("brand") String brand,
            @RequestParam("spec") String spec,
            @RequestParam("isAD") Boolean isAD,
            @RequestParam("status") Integer status) throws IOException {
        return itemService.inserts(name,price,stock,image,category,brand,spec,isAD,status);
    }

    /**
     *更新商品状态
     * @param id 商品id
     * @param status 状态码
     *
     */
    @PutMapping("/status/{id}/{status}")
    public void updateStatus(@PathVariable Integer id,@PathVariable Integer status){
        boolean b = itemService.updateStatus(id, status);

    }

    /**
     * 修改商品
     * @param item 商品实体
     *
     */
    @PutMapping
    public void updates(@RequestBody Item item){
        itemService.updates(item);
    }

    /**
     * 根据id删除商品
     * @param id 商品id
     *
     */
    @DeleteMapping("/{id}")
    public void delete(@PathVariable Long id) {
    itemService.delete(id);
    }

    /**
     * 批量扣减库存
     *
     */
    @PutMapping("/stock/deduct")
    public void deDuckStock(@RequestBody List<OrderDetailDTO> items){
        itemService.deDuckStock(items);
    }

    @GetMapping("/total-count")
    public Response<?> itemCount(){
        long totalItemCount = itemService.count();
        return Response.success(totalItemCount);
    }

    @GetMapping("/categories")
    public Response<?> categories(){
        return itemService.categories();
    }

    @GetMapping("/brands")
    public Response<?> brands(){
        return itemService.brands();
    }

    @GetMapping("/products")
    public Response<?> getItemList(
            SearchForm searchForm,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer size) {

        // 调用服务层获取分页数据
        IPage<Item> userPage = itemService.getItemList(searchForm, page, size);

        // 封装成统一响应格式返回
        return Response.success(userPage);
    }

    @GetMapping("/status/{itemId}")
    public Response<?> status(@PathVariable Long itemId){
        Item item = itemService.getById(itemId);
        Integer status = item.getStatus();
        if (status == 1){
            item.setStatus(2);
            itemService.updates(item);
            return Response.success(item.getStatus());
        }else {
            item.setStatus(1);
            itemService.updates(item);
            return Response.success(item.getStatus());
        }
    }

    @PutMapping("/batch/status")
    public Response<?> batchStatus(@RequestBody Map<String, Object> params) {
        List<Long> ids = (List<Long>) params.get("ids");
        Integer status = (Integer) params.get("status");
        return itemService.batchStatus(ids,status);
    }

    @PostMapping("/batch/delete")
    public Response<?> deleteBatch(@RequestBody List<Long> ids){
        itemService.removeBatchByIds(ids);
        return Response.success();
    }
}
